package ar.edu.unrn.lia.model;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;

import ar.edu.unrn.lia.util.FuncionesDate;

@Entity
@Table(name = "alquiler_cuota")
public class AlquilerCuota extends BaseEntity implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 7479273712468677445L;
	private static final int DIA_VENCIMIENTO = 10;
	private static final Double TASA_MENSUAL = 2.5;

	// TODO estado vencida por tarea programado todos los dias V("Vencida")
	public enum CoutaEstado {
		PE("Pendiente"), PT("Paga Total"), PP("Paga Parcial"), V("Vencida");

		private String rating;

		private CoutaEstado(String rating) {
			this.rating = rating;
		}

		@Override
		public String toString() {
			return rating;
		}
	}

	private Integer nroCuota;

	private Integer montoInquilino = 0;

	private Integer montoInquilinoPagado = 0;

	private Date fechaPago;

	private Integer montoPropietario = 0;

	private Alquiler alquiler;

	private Date fecha;

	private CoutaEstado estado = CoutaEstado.PE;

	private String color;

	public AlquilerCuota() {
		super();
		// TODO Auto-generated constructor stub
	}

	public AlquilerCuota(Integer nroCuota, Integer montoInquilino,
			Integer montoPropietario, Date fecha) {
		super();
		this.nroCuota = nroCuota;
		this.montoInquilino = montoInquilino;
		this.montoPropietario = montoPropietario;
		this.fecha = fecha;
	}

	@ManyToOne
	@JoinColumn(name = "alquiler_id", nullable = false)
	@NotNull(message = "{name.notnull}")
	public Alquiler getAlquiler() {
		return alquiler;
	}

	public void setAlquiler(Alquiler alquiler) {
		this.alquiler = alquiler;
	}

	@NotNull(message = "{name.notnull}")
	public Integer getNroCuota() {
		return nroCuota;
	}

	public void setNroCuota(Integer nroCuota) {
		this.nroCuota = nroCuota;
	}

	@NotNull(message = "{name.notnull}")
	public Integer getMontoInquilino() {
		return montoInquilino;
	}

	public void setMontoInquilino(Integer montoInquilino) {
		this.montoInquilino = montoInquilino;
	}

	public Integer getMontoPropietario() {
		return montoPropietario;
	}

	public void setMontoPropietario(Integer montoPropietario) {
		this.montoPropietario = montoPropietario;
	}

	@Temporal(TemporalType.DATE)
	@NotNull(message = "{name.notnull}")
	public Date getFecha() {
		return fecha;
	}

	public void setFecha(Date fecha) {
		this.fecha = fecha;
	}

	@NotNull(message = "{name.notnull}")
	@Enumerated(EnumType.STRING)
	public CoutaEstado getEstado() {
		return estado;
	}

	public void setEstado(CoutaEstado estado) {
		this.estado = estado;
	}

	public Integer getMontoInquilinoPagado() {
		return montoInquilinoPagado;
	}

	public void setMontoInquilinoPagado(Integer montoInquilinoPagado) {
		this.montoInquilinoPagado = montoInquilinoPagado;
	}

	@Temporal(TemporalType.DATE)
	public Date getFechaPago() {
		return fechaPago;
	}

	public void setFechaPago(Date fechaPago) {
		this.fechaPago = fechaPago;
	}
	
	public Date fechaVencimiento()
	{
		Calendar c = Calendar.getInstance();
		c.setTime(this.getFecha());
		c.add(Calendar.DATE, DIA_VENCIMIENTO-1);  
		return c.getTime();
	}
	
	public Double capitalCalculoVencimiento()
	{
		if (estadoVencida())
			return getMontoInquilino().doubleValue();
		else if (estadoPagoParcial())
			return montoDeudaPagoParcial().doubleValue();
		else
			return 0D;
	}
	

	@Transient
	public String getColor() {
		if (estadoPagoTotal()) {
			this.color = "grid-cuota-pt";
		} else if (estadoPagoParcial()) {
			this.color = "grid-cuota-pp";
		} else if (estadoVencida()) {
			this.color = "grid-cuota-alerta";
		} else {
			this.color = "grid-cuota-pe";
		}
		return color;
	}


	public void pagar(Integer montoPagar) {
		setMontoInquilinoPagado(getMontoInquilinoPagado() + montoPagar);
		setFechaPago(new Date());
		if (getMontoInquilino().equals(getMontoInquilinoPagado()))
			setEstado(CoutaEstado.PT);
		else
			setEstado(CoutaEstado.PP);

	}

	// TODO Pagar Todo lo que se pueda el alquiler Impago.
	public Double pagarImpagos(Double monto) {
		if (monto > 0) {
			Double dif = new Double(getMontoInquilino())
					- new Double(getMontoInquilinoPagado());
			if (dif <= monto) {
				setMontoInquilinoPagado(getMontoInquilino());
				setEstado(CoutaEstado.PT);
				monto = monto - dif;
			} else {
				setMontoInquilinoPagado(getMontoInquilinoPagado()
						+ dif.intValue());
				monto = new Double(0);
				setEstado(CoutaEstado.PP);
			}
		}
		return monto;
	}

	public Integer montoDeuda() {
		Integer resultado = 0;
		if (estadoPagoParcial()) {
			resultado = diferenciaPagoParcial();
		} else if (estadoVencida()) {
			resultado = getMontoInquilino();
		}
		return resultado;
	}

	public Integer montoDeudaVencida() {
		Integer resultado = 0;
		if (estadoVencida()) {
			resultado = getMontoInquilino();
		}
		return resultado;
	}

	public Integer montoDeudaPagoParcial() {
		Integer resultado = 0;
		if (estadoPagoParcial()) {
			resultado = diferenciaPagoParcial();
		}
		return resultado;
	}

	public Boolean estadoPagoTotal() {
		return getEstado().equals(CoutaEstado.PT);
	}

	public Boolean estadoPendientePago() {
		return getEstado().equals(CoutaEstado.PE);
	}

	public Boolean estadoPagoParcial() {
		return getEstado().equals(CoutaEstado.PP);
	}
	
	public Boolean estadoVencida() {
		return getEstado().equals(CoutaEstado.V);
	}

	public Integer diferenciaPagoParcial() {
		return getMontoInquilino() - getMontoInquilinoPagado();
	}

}
